﻿#include "GUISpectrogramResultDialog.h"
#include "ui_GUISpectrogramResultDialog.h"
#include "OperatorsInterface/GraphPostEventOperator.h"

#include "FITK_Component/FITKAcousticsModel/FITKAcousticsDiscModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsSEAModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAbstractSEASubSys.h"

#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsAbstractSpectra.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKSpectraPressure.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKSpectraVelocity.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKSpectraAlgorithm.h"

#include "FITK_Component/FITKAcousticsPostData/FITKAcousticsPostData.h"
#include "FITK_Component/FITKAcousticsPostData/FITKAcousticsContourPlotData.h"
#include "FITK_Component/FITKAcousticsPostData/FITKAcousticsHDF5AttributeObject.hpp"
#include "FITK_Component/FITKAcousticsPostData/FITKAcousticsHDF5Constants.h"
#include "FITK_Component/FITKAcousticsPostData/FITKAcousticsHDF5DataSet.hpp"
#include "FITK_Component/FITKAcousticsPostData/FITKAcousticsHDF5Frequencies.h"
#include "FITK_Component/FITKAcousticsPostData/FITKAcousticsHDF5LoadCase.h"

#include "FITK_Component/FITKRenderWindowVTK/FITKGraph3DWindowVTK.h"

#include "FITK_Kernel/FITKCore/FITKAbstractDataManager.hpp"
#include "FITK_Kernel/FITKCore/FITKOperatorRepo.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "FITK_Kernel/FITKAppFramework/FITKMessage.h"

#include <qmath.h>
#include <QPalette>
#include <QColorDialog>

namespace GUI
{
    GUISpectrogramResultDialog::GUISpectrogramResultDialog(Acoustics::FITKAcousticsContourPlotData* plotData, Core::FITKActionOperator* oper, QWidget *parent) :
        GUIDialogBase(parent),
        _plotData(plotData),
        _oper(oper),
        _ui(new Ui::GUISpectrogramResultDialog)
    {
        _ui->setupUi(this);
        // 去掉帮助按钮
        setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
        //初始化界面窗口
        this->initWidget();
        //初始化数据
        this->init();
    }

    GUISpectrogramResultDialog::~GUISpectrogramResultDialog()
    {
        //销毁
        if (_ui) delete _ui;
    }

    void GUISpectrogramResultDialog::on_pushButton_Apply_clicked()
    {
        //保存数据
        this->updateEngUnitData();
        this->saveData();
    }

    void GUISpectrogramResultDialog::on_pushButton_OK_clicked()
    {
        //保存数据
        this->updateEngUnitData();
        this->saveData();
        this->accept();
    }

    void GUISpectrogramResultDialog::on_pushButton_Close_clicked()
    {
        this->reject();
    }

    void GUISpectrogramResultDialog::on_checkBox_Display_clicked(bool checked)
    {
        //更新控件可用状态
        _ui->tabWidget->setTabEnabled(1, checked);
        _ui->tabWidget->setTabEnabled(2, checked);
        _ui->tabWidget->setTabEnabled(3, checked);
        _ui->radioButton_At->setEnabled(checked);
        _ui->radioButton_OverAllLevel->setEnabled(checked);
        _ui->comboBox_LoadCase->setEnabled(checked);
        _ui->comboBox_REsultType->setEnabled(checked);
        _ui->comboBox_EngUnitsType->setEnabled(checked);
        _ui->comboBox_Component->setEnabled(checked);
        _ui->comboBox_Location->setEnabled(checked);
        _ui->comboBox_Quantity->setEnabled(checked);
        _ui->comboBox_Hz->setEnabled(checked);
        //更新标题
        this->updateWidgetTitle();
    }

    void GUISpectrogramResultDialog::on_radioButton_At_clicked(bool checked)
    {
        //更新控件可用状态
        if (!checked) return;
        _ui->comboBox_Hz->setEnabled(true);
        this->on_comboBox_Hz_currentIndexChanged(_ui->comboBox_Hz->currentIndex());
    }

    void GUISpectrogramResultDialog::on_radioButton_OverAllLevel_clicked(bool checked)
    {
        //更新控件可用状态
        if (!checked) return;
        _ui->comboBox_Hz->setEnabled(false);
        //更新最大值最小值
        this->updateMaxMinData();
        //更新标题
        this->updateWidgetTitle();
    }

    void GUISpectrogramResultDialog::on_comboBox_Hz_currentIndexChanged(int index)
    {
        //更新最大值最小值
        this->updateMaxMinData();
        //更新标题
        this->updateWidgetTitle();
    }

    void GUISpectrogramResultDialog::on_comboBox_REsultType_currentIndexChanged(int index)
    {
        //更新标题
        this->updateWidgetTitle();
    }

    void GUISpectrogramResultDialog::on_comboBox_EngUnitsType_currentIndexChanged(int index)
    {
        //刷新标签页可用状态
        _ui->groupBox_Pressure->setEnabled(false);
        _ui->groupBox_Velocity->setEnabled(false);
        //通过选取类型设置状态
        Acoustics::FITKAcousticsContourPlotData::EngUnitsType type = Acoustics::FITKAcousticsContourPlotData::EngUnitsType(_ui->comboBox_EngUnitsType->currentData().toInt());
        if (type == Acoustics::FITKAcousticsContourPlotData::EngUnitsType::Pressure)
            _ui->groupBox_Pressure->setEnabled(true);
        else if (type == Acoustics::FITKAcousticsContourPlotData::EngUnitsType::Velocity)
            _ui->groupBox_Velocity->setEnabled(true);
    }

    void GUISpectrogramResultDialog::on_checkBox_Pressure_DB_clicked(bool checked)
    {
        //刷新标签页可用状态
        _ui->radioButton_Pressure_Linear->setEnabled(!checked);
        _ui->radioButton_Pressure_Log->setEnabled(!checked);
        _ui->lineEdit_Pressure_Ref->setEnabled(checked);
        //更新最大值最小值
        this->updateMaxMinData();
        //更新单位
        this->updatePressureUnit();
    }

    void GUISpectrogramResultDialog::on_checkBox_Velocity_DB_clicked(bool checked)
    {
        //刷新标签页可用状态
        _ui->radioButton_Velocity_Linear->setEnabled(!checked);
        _ui->radioButton_Velocity_Log->setEnabled(!checked);
        _ui->lineEdit_Velocity_Ref->setEnabled(checked);
        //更新最大值最小值
        this->updateMaxMinData();
        //更新单位
        this->updateVelocityUnit();
    }

    void GUISpectrogramResultDialog::on_checkBox_Pressure_A_clicked(bool checked)
    {
        //更新最大值最小值
        this->updateMaxMinData();
        //更新单位
        this->updatePressureUnit();
    }

    void GUISpectrogramResultDialog::on_checkBox_Velocity_A_clicked(bool checked)
    {
        //更新最大值最小值
        this->updateMaxMinData();
        //更新单位
        this->updateVelocityUnit();
    }

    void GUISpectrogramResultDialog::on_checkBox_Pressure_Auto_clicked(bool checked)
    {
        //设置组件是否可以输入
        _ui->lineEdit_Pressure_Min->setReadOnly(checked);
        _ui->lineEdit_Pressure_Max->setReadOnly(checked);
    }

    void GUISpectrogramResultDialog::on_checkBox_Velocity_Auto_clicked(bool checked)
    {
        //设置组件是否可以输入
        _ui->lineEdit_Velocity_Min->setReadOnly(checked);
        _ui->lineEdit_Velocity_Max->setReadOnly(checked);
    }

    void GUISpectrogramResultDialog::on_lineEdit_Velocity_Ref_textChanged(QString& text)
    {
        //更新最大值最小值
        this->updateMaxMinData();
    }

    void GUISpectrogramResultDialog::on_lineEdit_Pressure_Ref_textChanged(QString& text)
    {
        //更新最大值最小值
        this->updateMaxMinData();
    }

    void GUISpectrogramResultDialog::on_radioButton_Continuous_clicked(bool checked)
    {
        if (!checked)return;
        _ui->lineEdit_UserDiscrete->setEnabled(false);
    }

    void GUISpectrogramResultDialog::on_radioButton_UserDiscrete_clicked(bool checked)
    {
        if (!checked)return;
        _ui->lineEdit_UserDiscrete->setEnabled(true);
    }

    void GUISpectrogramResultDialog::on_pushButton_MaxColor_clicked()
    {
        //初始化
        QColorDialog dialog;
        dialog.setWindowTitle(tr("Select Color"));
        int result = dialog.exec();
        if (result != QDialog::Accepted) return;
        //设置颜色
        QString colorStr = dialog.currentColor().name();
        _ui->pushButton_MaxColor->setStyleSheet(QString("background-color: %1;").arg(colorStr));
    }

    void GUISpectrogramResultDialog::on_pushButton_MinColor_clicked()
    {
        //初始化
        QColorDialog dialog;
        dialog.setWindowTitle(tr("Select Color"));
        int result = dialog.exec();
        if (result != QDialog::Accepted) return;
        //设置颜色
        QString colorStr = dialog.currentColor().name();
        _ui->pushButton_MinColor->setStyleSheet(QString("background-color: %1;").arg(colorStr));
    }

    void GUISpectrogramResultDialog::on_checkBox_LineShow_clicked(bool checked)
    {
        _ui->pushButton_LineColor->setEnabled(checked);
    }

    void GUISpectrogramResultDialog::on_pushButton_LineColor_clicked()
    {
        //初始化
        QColorDialog dialog;
        dialog.setWindowTitle(tr("Select Color"));
        int result = dialog.exec();
        if (result != QDialog::Accepted) return;
        //设置颜色
        QString colorStr = dialog.currentColor().name();
        _ui->pushButton_LineColor->setStyleSheet(QString("background-color: %1;").arg(colorStr));
    }

    void GUISpectrogramResultDialog::init()
    {
        this->initFreqComboBox();
        this->initLoadCaseComboBox();
        this->initResultTypeComboBox();
        this->initEngineeringUnits();
        if (!_plotData) return;
        //获取数据
        bool isDisplay = _plotData->getDisplay();
        int freqIndex = _plotData->getSelectedHzIndex();
        QString loadCase = _plotData->getSelectedLoadCase();
        int engunitType = _plotData->getSelectedEngUnitsType();
        //设置界面数据
        _ui->checkBox_Display->setChecked(isDisplay);
        this->on_checkBox_Display_clicked(isDisplay);
        _ui->comboBox_Hz->setCurrentIndex(freqIndex);
        _ui->comboBox_LoadCase->setCurrentText(loadCase);
        int index = _ui->comboBox_EngUnitsType->findData(engunitType);
        _ui->comboBox_EngUnitsType->setCurrentIndex(index < 0 ? 0 : index);
        //Scaling
        _ui->radioButton_Velocity_Log->setChecked(_plotData->getVelocity_IsLog());
        _ui->radioButton_Velocity_Linear->setChecked(!_plotData->getVelocity_IsLog());
        _ui->checkBox_Velocity_DB->setChecked(_plotData->getVelocity_DB());
        _ui->checkBox_Velocity_Auto->setChecked(_plotData->getVelocity_Autoscale());
        _ui->lineEdit_Velocity_Ref->setText(QString::number(_plotData->getVelocity_Ref()));
        _ui->lineEdit_Velocity_Min->setText(QString::number(_plotData->getVelocity_Min()));
        _ui->lineEdit_Velocity_Max->setText(QString::number(_plotData->getVelocity_Max()));
        _ui->radioButton_Pressure_Log->setChecked(_plotData->getPressure_IsLog());
        _ui->radioButton_Pressure_Linear->setChecked(!_plotData->getPressure_IsLog());
        _ui->checkBox_Pressure_DB->setChecked(_plotData->getPressure_DB());
        _ui->checkBox_Pressure_Auto->setChecked(_plotData->getPressure_Autoscale());
        _ui->lineEdit_Pressure_Ref->setText(QString::number(_plotData->getPressure_Ref()));
        _ui->lineEdit_Pressure_Min->setText(QString::number(_plotData->getPressure_Min()));
        _ui->lineEdit_Pressure_Max->setText(QString::number(_plotData->getPressure_Max()));
        //初始化
        this->on_checkBox_Pressure_DB_clicked(_plotData->getPressure_DB());
        this->on_checkBox_Pressure_Auto_clicked(_plotData->getPressure_Autoscale());
        this->on_checkBox_Velocity_DB_clicked(_plotData->getVelocity_DB());
        this->on_checkBox_Velocity_Auto_clicked(_plotData->getVelocity_Autoscale());
        //WaveFields
        _ui->checkBox_Transverse_Flexure->setChecked(_plotData->getTransverse_Flexure());
        _ui->checkBox_In_plane_Extension->setChecked(_plotData->getIn_plane_Extension());
        _ui->checkBox_In_Plane_Shear->setChecked(_plotData->getIn_plane_Shear());
        _ui->checkBox_Flexure_X->setChecked(_plotData->getBeams_Flexure_X());
        _ui->checkBox_Flexure_Y->setChecked(_plotData->getBeams_Flexure_Y());
        _ui->checkBox_Extension->setChecked(_plotData->getBeams_Extension());
        _ui->checkBox_Torsion->setChecked(_plotData->getBeams_Torsion());
        //Display
        _ui->radioButton_Continuous->setChecked(_plotData->getIs_Colors_Continuous());
        _ui->radioButton_UserDiscrete->setChecked(!_plotData->getIs_Colors_Continuous());
        _ui->lineEdit_UserDiscrete->setText(QString::number(_plotData->getColors_Discrete_Use()));
        _ui->horizontalSlider_mid->setValue(100 - (_plotData->getTransparency_mid() * 100));
        _ui->horizontalSlider_max->setValue(100 - (_plotData->getTransparency_max() * 100));
        _ui->horizontalSlider_min->setValue(100 - (_plotData->getTransparency_min() * 100));
        _ui->pushButton_MaxColor->setStyleSheet(QString("background-color: %1;").arg(_plotData->getColor_max().name()));
        _ui->pushButton_MinColor->setStyleSheet(QString("background-color: %1;").arg(_plotData->getColor_min().name()));
        _ui->checkBox_LineShow->setChecked(_plotData->getIsLineShow());
        _ui->pushButton_LineColor->setStyleSheet(QString("background-color: %1;").arg(_plotData->getColor_Line().name()));
        //初始化
        this->on_checkBox_LineShow_clicked(_plotData->getIsLineShow());
        //更新标题
        this->updateWidgetTitle();
    }

    void GUISpectrogramResultDialog::initWidget()
    {
        QRegExp rExp = QRegExp("^[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?$");
        _ui->lineEdit_Pressure_Ref->setValidator(new QRegExpValidator(rExp));
        _ui->lineEdit_Pressure_Min->setValidator(new QRegExpValidator(rExp));
        _ui->lineEdit_Pressure_Max->setValidator(new QRegExpValidator(rExp));
        _ui->lineEdit_Velocity_Ref->setValidator(new QRegExpValidator(rExp));
        _ui->lineEdit_Velocity_Min->setValidator(new QRegExpValidator(rExp));
        _ui->lineEdit_Velocity_Max->setValidator(new QRegExpValidator(rExp));
    }

    void GUISpectrogramResultDialog::initFreqComboBox()
    {
        //获取后处理数据
        Acoustics::FITKAcousticsPostData* postData = FITKAPP->getGlobalData()->getPostData<Acoustics::FITKAcousticsPostData>();
        if (nullptr == postData) return;
        //获取后处理常数集数据
        Acoustics::FITKAcousticsHDF5Constants* constants = postData->getFITKAcousticsHDF5Constants();
        if (nullptr == constants) return;
        //获取后处理频率数据
        Acoustics::FITKAcousticsHDF5Frequencies* frequencies = constants->getFITKAcousticsHDF5Frequencies();
        if (nullptr == frequencies) return;
        //获取频率数据集
        Acoustics::FITKAcousticsHDF5DataSetManager* dataSetManager = frequencies->getFITKAcousticsHDF5DataSetManager();
        if (nullptr == dataSetManager) return;
        if (dataSetManager->getDataCount() <= 0) return;
        //获取频率第一个数据对象
        Acoustics::FITKAcousticsHDF5DataSet* dataSet = dataSetManager->getDataByIndex(0);
        if (nullptr == dataSet) return;
        QHash<int, std::vector<float>> hashValue = dataSet->getValues();
        if (hashValue.size() <= 0) return;
        //设置频率下拉框数据
        std::vector<float> freqData = hashValue.value(hashValue.keys().first());
        for (std::vector<float>::iterator iter = freqData.begin(); iter != freqData.end(); ++iter)
            _ui->comboBox_Hz->addItem(QString::number(*iter), *iter);
    }

    void GUISpectrogramResultDialog::initLoadCaseComboBox()
    {
        //获取后处理数据
        Acoustics::FITKAcousticsPostData* postData = FITKAPP->getGlobalData()->getPostData<Acoustics::FITKAcousticsPostData>();
        if (nullptr == postData) return;
        //获取工况载荷数据集
        Acoustics::FITKAcousticsHDF5LoadCaseManager* loadCaseManager = postData->getFITKAcousticsHDF5LoadCaseManager();
        if (nullptr == loadCaseManager) return;
        //设置载荷工况下拉框
        int count = loadCaseManager->getDataCount();
        for (int i = 0; i < count; i++)
        {
            //遍历所有工况根据索引
            Acoustics::FITKAcousticsHDF5LoadCase* loadCase = loadCaseManager->getDataByIndex(i);
            if (nullptr == loadCase) continue;
            _ui->comboBox_LoadCase->addItem(loadCase->getDataObjectName(), loadCase->getDataObjectID());
        }
    }

    void GUISpectrogramResultDialog::initResultTypeComboBox()
    {
        _ui->comboBox_REsultType->addItem("Engineering Units");
    }

    void GUISpectrogramResultDialog::initEngineeringUnits()
    {
        _ui->comboBox_EngUnitsType->addItem(tr("Pressure"), int(Acoustics::FITKAcousticsContourPlotData::EngUnitsType::Pressure));
        _ui->comboBox_EngUnitsType->addItem(tr("Velocity"), int(Acoustics::FITKAcousticsContourPlotData::EngUnitsType::Velocity));

        _ui->comboBox_Quantity->addItem("Magnitude");
    }

    void GUISpectrogramResultDialog::updateWidgetTitle()
    {
        QString title = tr("Contour Plot");
        //频率
        if (_ui->radioButton_At->isChecked() && _ui->comboBox_Hz->count() > 0)
            title += QString(" - %1 Hz").arg(_ui->comboBox_Hz->currentText());
        else if (_ui->radioButton_OverAllLevel->isChecked())
            title += QString(" - %1").arg("Overall Level");
        //结果类型
        if (_ui->checkBox_Display->isChecked() && _ui->comboBox_REsultType->count() > 0)
            title += QString(" - %1").arg(_ui->comboBox_REsultType->currentText());
        //设置标题
        this->setWindowTitle(title);
    }

    void GUISpectrogramResultDialog::updatePressureUnit()
    {
        //获取界面状态
        bool isDB = _ui->checkBox_Pressure_DB->isChecked();
        bool isA = _ui->checkBox_Pressure_A->isChecked();
        //获取单位
        QString unit = "Pa";
        if (isDB)
            unit = "dB";
        if (isDB && isA)
            unit = "dBA";
        _ui->label_Pressure_Min->setText(unit);
        _ui->label_Pressure_Max->setText(unit);
    }

    void GUISpectrogramResultDialog::updateVelocityUnit()
    {
        //获取界面状态
        bool isDB = _ui->checkBox_Velocity_DB->isChecked();
        bool isA = _ui->checkBox_Velocity_A->isChecked();
        //获取单位
        QString unit = "m/s";
        if (isDB)
            unit = "dB";
        if (isDB && isA)
            unit = "dBA";
        _ui->label_Velocity_Min->setText(unit);
        _ui->label_Velocity_Max->setText(unit);
    }

    Acoustics::FITKAcousticsHDF5ObjectManager* GUISpectrogramResultDialog::getSubsystemResultManager(QString loadCaseName)
    {
        //获取子系统结果数据管理器
        Acoustics::FITKAcousticsPostData* postData = FITKAPP->getGlobalData()->getPostData<Acoustics::FITKAcousticsPostData>();
        if (nullptr == postData) return nullptr;
        Acoustics::FITKAcousticsHDF5LoadCaseManager* loadCaseManager = postData->getFITKAcousticsHDF5LoadCaseManager();
        if (!loadCaseManager) return nullptr;
        Acoustics::FITKAcousticsHDF5LoadCase* selectLoadCase = loadCaseManager->getDataByName(loadCaseName);
        if (!selectLoadCase) return nullptr;
        //获取工况下子集
        Acoustics::FITKAcousticsHDF5ObjectManager* loadCaseChildManager = selectLoadCase->getFITKAcousticsHDF5ObjectChildManager();
        if (!loadCaseChildManager) return nullptr;
        Acoustics::FITKAcousticsHDF5Object* subSystems = loadCaseChildManager->getDataByName("SubSystems");//获取子系统节点
        if (!subSystems) return nullptr;
        //获取子系统子节点管理器
        Acoustics::FITKAcousticsHDF5ObjectManager* subSystemResultManager = subSystems->getFITKAcousticsHDF5ObjectChildManager();
        return subSystemResultManager;
    }

    double GUISpectrogramResultDialog::calcParaData(double value, double freqValue, bool isAWei, bool isDB, double dbUserValue)
    {
        double result = value;
        //计算db
        if (isDB)
        {
            result = 20 * log10(value / dbUserValue);
        }
        //计算A权
        if (isAWei)
        {
            double hz = this->getAWeightingValue(freqValue);
            result = result + hz;
        }
        return result;
    }

    double GUISpectrogramResultDialog::calcOverAllParaData(double value, bool isDB, bool isAll)
    {
        double result = value;
        if (isDB)
        {
            if (isAll)
                result = 10 * log10(value);
            else
                result = qPow(10, (0.1 * value));
        }
        return result;
    }

    void GUISpectrogramResultDialog::updateMaxMinData()
    {
        Acoustics::FITKAcousticsContourPlotData::EngUnitsType engUnitsType = Acoustics::FITKAcousticsContourPlotData::EngUnitsType(_ui->comboBox_EngUnitsType->currentData().toInt());
        if (engUnitsType == Acoustics::FITKAcousticsContourPlotData::EngUnitsType::Pressure && !_ui->checkBox_Pressure_Auto->isChecked())
            return;
        if (engUnitsType == Acoustics::FITKAcousticsContourPlotData::EngUnitsType::Velocity && !_ui->checkBox_Velocity_Auto->isChecked())
            return;
        //获取结果数据
        QHash<QString, float> resultData = this->getEngUnitData();
        QList<float> listMathData = resultData.values();
        if (listMathData.isEmpty()) return;
        //计算最大、最小值
        float fMax = listMathData.at(0), fMin = listMathData.at(0);
        for (QList<float>::iterator iter = listMathData.begin() + 1; iter != listMathData.end(); ++iter)
        {
            fMax = qMax(*iter, fMax);
            fMin = qMin(*iter, fMin);
        }
        //更新界面
        if (engUnitsType == Acoustics::FITKAcousticsContourPlotData::EngUnitsType::Pressure && _ui->checkBox_Pressure_Auto->isChecked())
        {
            _ui->lineEdit_Pressure_Min->setText(QString::number(fMin));
            _ui->lineEdit_Pressure_Max->setText(QString::number(fMax));
        }
        else if (engUnitsType == Acoustics::FITKAcousticsContourPlotData::EngUnitsType::Velocity && _ui->checkBox_Velocity_Auto->isChecked())
        {
            _ui->lineEdit_Velocity_Min->setText(QString::number(fMin));
            _ui->lineEdit_Velocity_Max->setText(QString::number(fMax));
        }
    }

    void GUISpectrogramResultDialog::updateEngUnitData()
    {
        //获取结果数据
        QHash<QString, float> resultData = this->getEngUnitData();
        QList<float> listMathData = resultData.values();
        if (listMathData.isEmpty()) return;
        //计算最大、最小值
        Acoustics::FITKAcousticsContourPlotData::EngUnitsType engUnitsType = Acoustics::FITKAcousticsContourPlotData::EngUnitsType(_ui->comboBox_EngUnitsType->currentData().toInt());
        float fMax = listMathData.at(0), fMin = listMathData.at(0);
        if (engUnitsType == Acoustics::FITKAcousticsContourPlotData::EngUnitsType::Pressure && !_ui->checkBox_Pressure_Auto->isChecked())
        {
            fMax = _ui->lineEdit_Pressure_Max->text().toFloat();
            fMin = _ui->lineEdit_Pressure_Max->text().toFloat();
        }
        else if (engUnitsType == Acoustics::FITKAcousticsContourPlotData::EngUnitsType::Velocity && !_ui->checkBox_Velocity_Auto->isChecked())
        {
            fMax = _ui->lineEdit_Velocity_Max->text().toFloat();
            fMin = _ui->lineEdit_Velocity_Max->text().toFloat();
        }
        else
        {
            for (QList<float>::iterator iter = listMathData.begin() + 1; iter != listMathData.end(); ++iter)
            {
                fMax = qMax(*iter, fMax);
                fMin = qMin(*iter, fMin);
            }
        }
        //是否启用log
        bool isLogPlot = false;
        if (engUnitsType == Acoustics::FITKAcousticsContourPlotData::EngUnitsType::Pressure && !_ui->checkBox_Pressure_DB->isChecked())
            isLogPlot = _ui->radioButton_Pressure_Log->isChecked();
        else if (engUnitsType == Acoustics::FITKAcousticsContourPlotData::EngUnitsType::Velocity && !_ui->checkBox_Velocity_DB->isChecked())
            isLogPlot = _ui->radioButton_Velocity_Log->isChecked();
        //获取名称
        QString barName = this->getEngUnitPlotName();
        //获取是否启用云图
        bool isEnablePlot = _ui->checkBox_Display->isChecked();
        //获取色带数量
        int colors = 16;
        if (_ui->radioButton_UserDiscrete->isChecked())
            colors = _ui->lineEdit_UserDiscrete->text().toInt();
        //获取透明的和颜色
        double transparencyMid = (100 - _ui->horizontalSlider_mid->value()) / 100;
        double transparencyMax = (100 - _ui->horizontalSlider_max->value()) / 100;
        double transparencyMin = (100 - _ui->horizontalSlider_min->value()) / 100;
        QColor colorMax = _ui->pushButton_MaxColor->palette().color(QPalette::ColorRole::Background);
        QColor colorMin = _ui->pushButton_MinColor->palette().color(QPalette::ColorRole::Background);
        //算法计算后的数据 传递给 GraphPostEventOperator
        EventOper::GraphPostEventOperator* postOper = Core::FITKOperatorRepo::getInstance()->
            getOperatorT<EventOper::GraphPostEventOperator>("GraphPost");
        if (!postOper) return;
        //传递数据
        postOper->setEnableLogScale(isLogPlot, dynamic_cast<Comp::FITKGraph3DWindowVTK*>(this->parent()));
        postOper->setColorScalarNumber(colors, dynamic_cast<Comp::FITKGraph3DWindowVTK*>(this->parent()));
        postOper->setRangeColor(QColor(0, 0, 255), QColor(255, 0, 0), transparencyMid, dynamic_cast<Comp::FITKGraph3DWindowVTK*>(this->parent()));
        postOper->setAboveRangeColor(colorMax, transparencyMax, dynamic_cast<Comp::FITKGraph3DWindowVTK*>(this->parent()));
        postOper->setBelowRangeColor(colorMin, transparencyMin, dynamic_cast<Comp::FITKGraph3DWindowVTK*>(this->parent()));
        postOper->updatePostData(resultData, barName, fMin, fMax, dynamic_cast<Comp::FITKGraph3DWindowVTK*>(this->parent()));
        //取消云图
        if (!isEnablePlot)
            postOper->disablePostData(dynamic_cast<Comp::FITKGraph3DWindowVTK*>(this->parent()));
    }

    QString GUISpectrogramResultDialog::getEngUnitPlotName()
    {
        QString barName;
        Acoustics::FITKAcousticsContourPlotData::EngUnitsType engUnitsType = Acoustics::FITKAcousticsContourPlotData::EngUnitsType(_ui->comboBox_EngUnitsType->currentData().toInt());
        //获取频率数据
        if (_ui->radioButton_At->isChecked() && _ui->comboBox_Hz->count() > 0)
            barName += QString("%1 Hz\n").arg(_ui->comboBox_Hz->currentText());
        else if (_ui->radioButton_OverAllLevel->isChecked())
            barName += QString("%1\n").arg("Overall Level");
        if (_ui->comboBox_EngUnitsType->count() > 0)
            barName += QString("%1 Magnitude RMS\n").arg(_ui->comboBox_EngUnitsType->currentText());
        bool isDB = false, isA = false;
        double ref = 0.0;
        QString unit;
        //获取DB, A权，单位
        if (engUnitsType == Acoustics::FITKAcousticsContourPlotData::EngUnitsType::Pressure)
        {
            isDB = _ui->checkBox_Pressure_DB->isChecked();
            isA = _ui->checkBox_Pressure_A->isChecked();
            ref = _ui->lineEdit_Pressure_Ref->text().toDouble();
            unit = "Pa";
        }
        else if (engUnitsType == Acoustics::FITKAcousticsContourPlotData::EngUnitsType::Velocity)
        {
            isDB = _ui->checkBox_Velocity_DB->isChecked();
            isA = _ui->checkBox_Velocity_A->isChecked();
            ref = _ui->lineEdit_Velocity_Ref->text().toDouble();
            unit = "m/s";
        }
        if (isDB)
        {
            if (isA)
                barName += QString("dBA\n");
            else
                barName += QString("dB\n");
            barName += QString("ref=%1 %2\n").arg(QString::number(ref)).arg(unit);
        }
        else if (isA)
        {
            barName += QString("%1(A-weighted)\n").arg(unit);
        }
        else
        {
            barName += QString("%1\n").arg(unit);
        }
        return barName;
    }

    QHash<QString, float> GUISpectrogramResultDialog::getEngUnitData()
    {
        QHash<QString, float> resultData;
        if (!_SEAModel) return resultData;
        //获取选择工况载荷名称和工程类型
        QString loadCaseName = _ui->comboBox_LoadCase->currentText();
        Acoustics::FITKAcousticsContourPlotData::EngUnitsType engUnitsType = Acoustics::FITKAcousticsContourPlotData::EngUnitsType(_ui->comboBox_EngUnitsType->currentData().toInt());
        //获取算法类型
        bool isDB = false, isAWei = false;
        double dbUserValue = 0.0;
        //获取是否计算DB
        if (engUnitsType == Acoustics::FITKAcousticsContourPlotData::EngUnitsType::Velocity && _ui->checkBox_Velocity_DB->isChecked())
        {
            isDB = true;
            dbUserValue = _ui->lineEdit_Velocity_Ref->text().toDouble();
        }
        else if (engUnitsType == Acoustics::FITKAcousticsContourPlotData::EngUnitsType::Pressure && _ui->checkBox_Pressure_DB->isChecked())
        {
            isDB = true;
            dbUserValue = _ui->lineEdit_Pressure_Ref->text().toDouble();
        }
        //获取是否计算A权
        if (engUnitsType == Acoustics::FITKAcousticsContourPlotData::EngUnitsType::Velocity && _ui->checkBox_Velocity_A->isChecked())
            isAWei = true;
        else if (engUnitsType == Acoustics::FITKAcousticsContourPlotData::EngUnitsType::Pressure && _ui->checkBox_Pressure_A->isChecked())
            isAWei = true;
        //获取子系统结果数据管理器
        Acoustics::FITKAcousticsHDF5ObjectManager* subSystemResultManager = this->getSubsystemResultManager(loadCaseName);
        if (!subSystemResultManager) return resultData;
        //获取子系统数据
        Acoustics::FITKAcousticsSEASubSysManager* subsysDataManager = _SEAModel->getSEASubSysManager();
        if (!subsysDataManager)return resultData;
        int count = subsysDataManager->getDataCount();
        for (int i = 0; i < count; ++i)
        {
            Acoustics::FITKAbstractSEASubSys* subSys = subsysDataManager->getDataByIndex(i);
            if (!subSys) continue;
            //获取子系统名称和类型
            QString subSysName = subSys->getDataObjectName();
            Acoustics::FITKAbstractSEASubSys::SEASubSysType subsysType = subSys->getSEASubSysType();
            //获取结果数据管理
            Acoustics::FITKAcousticsHDF5Object* subSysPostItem = subSystemResultManager->getDataByName(subSysName);
            if (!subSysPostItem) continue;
            Acoustics::FITKAcousticsHDF5DataSetManager* dataSetManager = subSysPostItem->getFITKAcousticsHDF5DataSetManager();
            if (!dataSetManager) continue;
            //获取数据
            QStringList dataSetNameList;
            //压力工程类型 子系统必须是声腔
            if (engUnitsType == Acoustics::FITKAcousticsContourPlotData::EngUnitsType::Pressure && subsysType == Acoustics::FITKAbstractSEASubSys::SEACavity)
            {
                //获取第一个数据
                if (dataSetManager->getDataCount() > 0 && dataSetManager->getDataByIndex(0))
                    dataSetNameList.append(dataSetManager->getDataByIndex(0)->getDataObjectName());
            }
            //速度工程类型 子系统是梁
            else if (engUnitsType == Acoustics::FITKAcousticsContourPlotData::EngUnitsType::Velocity && subsysType == Acoustics::FITKAbstractSEASubSys::SEABeam)
            {
                if (_ui->checkBox_Flexure_X->isChecked())
                    dataSetNameList.append(QString("%1X").arg(subSysName));
                if (_ui->checkBox_Flexure_Y->isChecked())
                    dataSetNameList.append(QString("%1Y").arg(subSysName));
                if (_ui->checkBox_Extension->isChecked())
                    dataSetNameList.append(QString("%1E").arg(subSysName));
                if (_ui->checkBox_Torsion->isChecked())
                    dataSetNameList.append(QString("%1T").arg(subSysName));
            }
            //速度工程类型 子系统是板
            else if (engUnitsType == Acoustics::FITKAcousticsContourPlotData::EngUnitsType::Velocity && (subsysType == Acoustics::FITKAbstractSEASubSys::SEAFlatPlate ||
                subsysType == Acoustics::FITKAbstractSEASubSys::SEADoublyCurvedShell ||
                subsysType == Acoustics::FITKAbstractSEASubSys::SEASinglyCurvedShell ||
                subsysType == Acoustics::FITKAbstractSEASubSys::SEACylinderShell))
            {
                if (_ui->checkBox_Transverse_Flexure->isChecked())
                    dataSetNameList.append(QString("%1F").arg(subSysName));
                if (_ui->checkBox_In_plane_Extension->isChecked())
                    dataSetNameList.append(QString("%1E").arg(subSysName));
                if (_ui->checkBox_In_Plane_Shear->isChecked())
                    dataSetNameList.append(QString("%1S").arg(subSysName));
            }
            //其他类型
            else
                continue;
            //获取数据集
            QList<std::vector<float>> vecFloatsList;
            for (QStringList::iterator iterSetName = dataSetNameList.begin(); iterSetName != dataSetNameList.end(); ++iterSetName) {
                Acoustics::FITKAcousticsHDF5DataSet* dataSet = dataSetManager->getDataByName(*iterSetName);
                if (!dataSet) continue;
                QHash<int, std::vector<float>> hashValue = dataSet->getValues();
                if (hashValue.size() == 0)  continue;
                //默认只有一列数据
                vecFloatsList.append(hashValue.value(hashValue.keys().first()));
            }
            float fResult = .0f;
            //OverAll Level
            if (_ui->radioButton_OverAllLevel->isChecked()) {
                int freqCount = _ui->comboBox_Hz->count();
                for (int freqIndex = 0; freqIndex < freqCount; ++freqIndex) {
                    double resultValue = 0.0;
                    for (QList<std::vector<float>>::iterator iter = vecFloatsList.begin(); iter != vecFloatsList.end(); ++iter) {
                        if (iter->size() < freqIndex) continue;
                        resultValue += qPow(iter->at(freqIndex), 2);
                    }
                    resultValue = qSqrt(resultValue);
                    resultValue = this->calcParaData(resultValue, _ui->comboBox_Hz->currentData().toDouble(), isAWei, isDB, dbUserValue);
                    fResult += this->calcOverAllParaData(resultValue, isDB, false);
                }
                fResult = this->calcOverAllParaData(fResult, isDB, true);
            }
            //频率
            else {
                for (QList<std::vector<float>>::iterator iter = vecFloatsList.begin(); iter != vecFloatsList.end(); ++iter) {
                    if (iter->size() < _ui->comboBox_Hz->currentIndex()) continue;
                    fResult += qPow(iter->at(_ui->comboBox_Hz->currentIndex()), 2);
                }
                fResult = qSqrt(fResult);
                //处理 DB 与A计权 数据处理
                fResult = this->calcParaData(fResult, _ui->comboBox_Hz->currentData().toDouble(), isAWei, isDB, dbUserValue);
            }
            resultData.insert(subSysName, fResult);
        }
        return resultData;
    }

    void GUISpectrogramResultDialog::saveData()
    {
        if (!_plotData) return;
        //General
        _plotData->setDisplay(_ui->checkBox_Display->isChecked());
        _plotData->setSelectedHzIndex(_ui->comboBox_Hz->currentIndex());
        _plotData->setSelectedLoadCase(_ui->comboBox_LoadCase->currentText());
        _plotData->setSelectedEngUnitsType(Acoustics::FITKAcousticsContourPlotData::EngUnitsType(_ui->comboBox_EngUnitsType->currentData().toInt()));
        //Scaling
        _plotData->setVelocity_IsLog(_ui->radioButton_Velocity_Log->isChecked());
        _plotData->setVelocity_DB(_ui->checkBox_Velocity_DB->isChecked());
        _plotData->setVelocity_Autoscale(_ui->checkBox_Velocity_Auto->isChecked());
        _plotData->setVelocity_Ref(_ui->lineEdit_Velocity_Ref->text().toDouble());
        _plotData->setVelocity_Min(_ui->lineEdit_Velocity_Min->text().toDouble());
        _plotData->setVelocity_Max(_ui->lineEdit_Velocity_Max->text().toDouble());

        _plotData->setPressure_IsLog(_ui->radioButton_Pressure_Log->isChecked());
        _plotData->setPressure_DB(_ui->checkBox_Pressure_DB->isChecked());
        _plotData->setPressure_Autoscale(_ui->checkBox_Pressure_Auto->isChecked());
        _plotData->setPressure_AWeighting(_ui->checkBox_Pressure_A->isChecked());
        _plotData->setPressure_Ref(_ui->lineEdit_Pressure_Ref->text().toDouble());
        _plotData->setPressure_Min(_ui->lineEdit_Pressure_Min->text().toDouble());
        _plotData->setPressure_Max(_ui->lineEdit_Pressure_Max->text().toDouble());
        //WaveFields
        _plotData->setTransverse_Flexure(_ui->checkBox_Transverse_Flexure->isChecked());
        _plotData->setIn_plane_Extension(_ui->checkBox_In_plane_Extension->isChecked());
        _plotData->setIn_plane_Shear(_ui->checkBox_In_Plane_Shear->isChecked());

        _plotData->setBeams_Flexure_X(_ui->checkBox_Flexure_X->isChecked());
        _plotData->setBeams_Flexure_Y(_ui->checkBox_Flexure_Y->isChecked());
        _plotData->setBeams_Extension(_ui->checkBox_Extension->isChecked());
        _plotData->setBeams_Torsion(_ui->checkBox_Torsion->isChecked());
        //Display
        _plotData->setIs_Colors_Continuous(_ui->radioButton_Continuous->isChecked());
        _plotData->setColors_Discrete_Use(_ui->lineEdit_UserDiscrete->text().toInt());
        _plotData->setTransparency_mid((100 - _ui->horizontalSlider_mid->value()) / 100);
        _plotData->setTransparency_max((100 - _ui->horizontalSlider_max->value()) / 100);
        _plotData->setTransparency_min((100 - _ui->horizontalSlider_min->value()) / 100);
        _plotData->setColor_max(_ui->pushButton_MaxColor->palette().color(QPalette::ColorRole::Background));
        _plotData->setColor_min(_ui->pushButton_MinColor->palette().color(QPalette::ColorRole::Background));
        _plotData->setIsLineShow(_ui->checkBox_LineShow->isChecked());
        _plotData->setColor_Line(_ui->pushButton_LineColor->palette().color(QPalette::ColorRole::Background));
    }

    double GUISpectrogramResultDialog::getAWeightingValue(double freq)
    {
        //获取A权数据
        double value = 0.0;
        if (freq - 10.0 < 1e-16) value = -70.4;
        else if (freq - 12.5 < 1e-16) value = -63.4;
        else if (freq - 16 < 1e-16) value = -56.7;
        else if (freq - 20 < 1e-16) value = -50.5;
        else if (freq - 25 < 1e-16) value = -44.7;
        else if (freq - 31.5 < 1e-16) value = -39.4;
        else if (freq - 40 < 1e-16) value = -34.6;
        else if (freq - 50 < 1e-16) value = -30.2;
        else if (freq - 63 < 1e-16) value = -26.2;
        else if (freq - 80 < 1e-16) value = -22.5;
        else if (freq - 100 < 1e-16) value = -19.1;
        else if (freq - 125 < 1e-16) value = -16.1;
        else if (freq - 160 < 1e-16) value = -13.4;
        else if (freq - 200 < 1e-16) value = -10.9;
        else if (freq - 250 < 1e-16) value = -8.6;
        else if (freq - 315 < 1e-16) value = -6.6;
        else if (freq - 400 < 1e-16) value = -4.8;
        else if (freq - 500 < 1e-16) value = -3.2;
        else if (freq - 630 < 1e-16) value = -1.9;
        else if (freq - 800 < 1e-16) value = -0.8;
        else if (freq - 1000 < 1e-16) value = 0.0;
        else if (freq - 1250 < 1e-16) value = 0.6;
        else if (freq - 1600 < 1e-16) value = 1.0;
        else if (freq - 2000 < 1e-16) value = 1.2;
        else if (freq - 2500 < 1e-16) value = 1.3;
        else if (freq - 3150 < 1e-16) value = 1.2;
        else if (freq - 4000 < 1e-16) value = 1;
        else if (freq - 5000 < 1e-16) value = 0.5;
        else if (freq - 6300 < 1e-16) value = -0.1;
        else if (freq - 8000 < 1e-16) value = -1.1;
        else if (freq - 10000 < 1e-16) value = -2.5;
        else if (freq - 12500 < 1e-16) value = -4.3;
        else if (freq - 16000 < 1e-16) value = -6.6;
        else if (freq - 20000 < 1e-16) value = -9.3;
        else value = -9.3;
        return value;
    }
}

